#ifndef MYSQL_CONNECTION_POOL_H
#define MYSQL_CONNECTION_POOL_H

#include <iostream>
#include <string>
#include <queue>
#include <mysql/mysql.h>
#include "../lock/locker.h"
#include "../log/logger.h"

using namespace std;


class MySqlConnPool {
public:
    // 单例模式
    static MySqlConnPool *get_instance();     // 获取单例

    void init(const char *url, uint32_t port, const char *name,
              const char *uname, const char *passwd, uint32_t max_conns);     // 连接池初始化
    MYSQL *get_connection();                  // 获取一个MySql访问连接
    bool release_connection(MYSQL *conn);    // 释放一个访问连接
    void close_pool();                       // 销毁连接池
    int get_free_num();                      // 获取当前空闲连接数量


private:
    MySqlConnPool();
    ~MySqlConnPool();
    MySqlConnPool(const MySqlConnPool &) = default;
    MySqlConnPool & operator = (MySqlConnPool const &) = default;

private:
    int m_maxConns;
    int m_busyConns;
    int m_freeConns;

    queue<MYSQL *> m_connQueue;    // 连接池队列
    Locker m_locker;             // 连接池访问锁
    Semaphore m_sem_reserve;     // 连接池资源数信号量

};


class MySqlConn {
    // RAII
public:
    explicit MySqlConn(MYSQL **sqlConn);
    MySqlConn();
    ~MySqlConn();

    [[nodiscard]] MYSQL *get() const;

public:
    MYSQL *m_sqlConn;
    MySqlConnPool *m_sqlPool;

private:
    void init_raii();
};

#endif //MYSQL_CONNECTION_POOL_H
